import { ref, computed } from 'vue';
import type { WorkflowTemplate, ParamNode } from '@/types';
import { ParamType } from './index';

export class ParamManager {
    private params = ref<ParamNode[]>([]);
    private workflowJson = ref<any>(null);

    // 获取所有参数
    getParams() {
        return this.params.value;
    }

    // 设置工作流 JSON
    setWorkflowJson(json: any) {
        this.workflowJson.value = json;
        this.autoDetectParams();
    }

    // 自动检测参数
    private autoDetectParams() {
        if (!this.workflowJson.value) return;

        const nodes = this.workflowJson.value.nodes || {};
        const detectedParams: ParamNode[] = [];

        // 遍历所有节点
        Object.entries(nodes).forEach(([nodeId, node]: [string, any]) => {
            // 检查节点类型
            const paramType = this.detectNodeType(node);
            if (paramType) {
                detectedParams.push(this.createParam(nodeId, node, paramType));
            }

            // 检查节点输入
            if (node.inputs) {
                Object.entries(node.inputs).forEach(([inputId, input]: [string, any]) => {
                    if (input.configurable) {
                        detectedParams.push(this.createInputParam(nodeId, inputId, input));
                    }
                });
            }
        });

        this.params.value = detectedParams;
    }

    // 添加参数
    addParam(type: ParamType = ParamType.Text) {
        const param: ParamNode = {
            id: `param_${Date.now()}`,
            nodeId: '',
            inputId: '',
            type,
            label: '新参数',
            value: null,
            config: {},
            help: ''
        };
        this.params.value.push(param);
    }

    // 更新参数
    updateParam(id: string, updates: Partial<ParamNode>) {
        const index = this.params.value.findIndex(p => p.id === id);
        if (index > -1) {
            this.params.value[index] = { ...this.params.value[index], ...updates };
        }
    }

    // 移动参数
    moveParam(fromIndex: number, toIndex: number) {
        const param = this.params.value[fromIndex];
        this.params.value.splice(fromIndex, 1);
        this.params.value.splice(toIndex, 0, param);
    }

    // 删除参数
    removeParam(id: string) {
        const index = this.params.value.findIndex(p => p.id === id);
        if (index > -1) {
            this.params.value.splice(index, 1);
        }
    }

    // 获取参数值
    getParamValues(): Record<string, any> {
        const values: Record<string, any> = {};
        this.params.value.forEach(param => {
            if (param.nodeId && param.inputId) {
                values[`${param.nodeId}.${param.inputId}`] = param.value;
            }
        });
        return values;
    }

    // 应用参数值到工作流
    applyParamsToWorkflow(workflow: Partial<WorkflowTemplate>) {
        if (!workflow.comfyuiJson) return workflow;

        const json = typeof workflow.comfyuiJson === 'string'
            ? JSON.parse(workflow.comfyuiJson)
            : workflow.comfyuiJson;

        // 更新节点参数
        this.params.value.forEach(param => {
            if (param.nodeId && param.inputId && json.nodes[param.nodeId]) {
                if (!json.nodes[param.nodeId].inputs) {
                    json.nodes[param.nodeId].inputs = {};
                }
                json.nodes[param.nodeId].inputs[param.inputId] = param.value;
            }
        });

        return {
            ...workflow,
            comfyuiJson: json,
            params: this.params.value
        };
    }

    private detectNodeType(node: any): ParamType | null {
        if (!node?.class_type) return null;

        switch (node.class_type) {
            case 'CLIPTextEncode':
                return ParamType.Text;
            case 'EmptyLatentImage':
                return ParamType.Number;
            case 'KSampler':
                return ParamType.Slider;
            case 'CheckpointLoaderSimple':
                return ParamType.Model;
            case 'LoadImage':
                return ParamType.Image;
            default:
                return null;
        }
    }

    private createParam(nodeId: string, node: any, type: ParamType): ParamNode {
        return {
            id: nodeId,
            nodeId,
            inputId: '',
            type,
            label: node.title || nodeId,
            value: null,
            config: this.getDefaultConfig(type),
            help: `节点 ID: ${nodeId}`
        };
    }

    private createInputParam(nodeId: string, inputId: string, input: any): ParamNode {
        return {
            id: `${nodeId}_${inputId}`,
            nodeId,
            inputId,
            type: input.type || ParamType.Text,
            label: input.label || inputId,
            value: input.default,
            config: input,
            help: input.help
        };
    }

    private getDefaultConfig(type: ParamType): Record<string, any> {
        switch (type) {
            case ParamType.Number:
            case ParamType.Slider:
                return { min: 0, max: 100, step: 1 };
            case ParamType.Select:
                return { options: [] };
            case ParamType.Boolean:
                return { activeText: '是', inactiveText: '否' };
            case ParamType.Color:
                return { showAlpha: true };
            default:
                return {};
        }
    }
} 